/****************************************************************************
*                                                                           *
* Copyright (c) Ionescu M. Marius. All rights reserved(2010).               *
*                                                                           *
****************************************************************************/

using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Web.Security;
using System.Web.UI.WebControls;
using NS_Controls;
using System.Web.UI;

public partial class EvaluationFile : SessionPageBase
{
    private static string sessionKey = "ds_Contracted";

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            if (!IsPostBack)
            {
                ClearSession(sessionKey);
                LoadData(false);
            }
            else
                CheckGridColumns();
        }
        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
        }
    }

    public void LoadData(bool bForce)
    {
        try
        {
            //month:
            DataSet ds = Hipocrate.DB.DBConnection.GetData("select [ID], [MonthName], case WHEN MONTH(GETDATE()) -1 = [ID] THEN 1 else	0 END as IsCurrentMonth from MONTH_NAMES where Active=1 order by ID");
            strMonthVerif.DataSource = ds;
            strMonthVerif.DataBind();
            strMonthStart.DataSource = ds;
            strMonthStart.DataBind();
            strMonthEnd.DataSource = ds;
            strMonthEnd.DataBind();

            for (int i = 0; i < ds.Tables[0].Rows.Count; ++i)
                if ((int)(ds.Tables[0].Rows[i]["IsCurrentMonth"]) == 1)
                {
                    strMonthVerif.Items[i].Selected = true;
                    strMonthStart.Items[i].Selected = true;
                    strMonthEnd.Items[i].Selected = true;
                }

            //year:
            ds = Hipocrate.DB.DBConnection.GetData("select [ID], [Code], case WHEN YEAR(GETDATE()) = Code THEN 1 else	0 END as IsCurrentYear from YEARS where Active=1 order by Code DESC");
            strYearVerif.DataSource = ds;
            strYearVerif.DataBind();
            strYear.DataSource = ds;
            strYear.DataBind();
            for (int i = 0; i < strYear.Items.Count; ++i)
                if ((int)(ds.Tables[0].Rows[i]["IsCurrentYear"]) == 1)
                {
                    strYearVerif.Items[i].Selected = true;
                    strYear.Items[i].Selected = true;
                }
            CheckInterval(false);

            if (!bForce) // page is loaded for the first time:
            {
                //calendarExtenders:
                startValDate.SelectedDate = DateTime.Now.Date;
                endValDate.SelectedDate = DateTime.Now.Date;
            }

            if (Hipocrate.DB.DBConnection.GetData("SELECT * FROM IND_FACTORS").Tables[0].Rows.Count == 0)
            {
                noFactors.Visible = true;
                validatedReports.Visible = false;
            }
            else
            {
                DataSet dsValidReports = Hipocrate.DB.DBConnection.GetData(@"SELECT DISTINCT '0' as NrCrt, IRFH.ID, IRFH.UserName, MN.MonthName, Y.Code AS [Year], IRFH.IDMonth, IRFH.IDYear, CONVERT(VARCHAR(17),IRFH.ExecDate,113) AS ExecDate
				from IND_REPORT_FACTORS IRF
				INNER JOIN IND_REPORT_FACTORS_HISTORY IRFH ON IRF.IDHistory = IRFH.ID
				INNER JOIN MONTH_NAMES MN ON IRFH.IDMONTH = MN.ID
				INNER JOIN YEARS Y ON IRFH.IDYear = Y.ID
				Where IRF.Valid = 1
				ORDER BY IRFH.IDYear DESC, IRFH.IDMonth  DESC");
                if (dsValidReports.Tables[0].Rows.Count == 0)
                {
                    noValidatedReports.Visible = true;
                    validatedReports.Visible = false;
                }
                else
                {
                    validatedReports.DataSource = dsValidReports;
                    validatedReports.DataBind();
                }
            }

            if (!IsPostBack)
            {
                startValDateStr.Text = DateTime.Now.ToString(startValDate.Format);
                endValDateStr.Text = DateTime.Now.ToString(endValDate.Format);
            }
            Load_Grid(bForce);
        }
        catch (Exception ex)
        {
            noFactors.Visible = true;
            Response.Write("test");
            this.Master.SetMessage(ex.Message, true);
            noFactors.Text += "<!--" + ex.ToString() + "-->";
        }
    }

    private void Load_Grid(bool bForceReload)
    {
        string sqlQuery = "(not set)";
        try
        {
            DataSet ds_Contracted = GetSession(sessionKey) as DataSet;
            if (ds_Contracted == null || bForceReload)
            {
                sqlQuery = GetSqlQueryForContracts();
                ds_Contracted = Hipocrate.DB.DBConnection.GetData(sqlQuery);

                foreach (DataTable dt in ds_Contracted.Tables)
                    foreach (DataColumn dc in dt.Columns)
                    {
                        dc.ReadOnly = false;
                        dc.AllowDBNull = true;
                    }

                SetSession(sessionKey, ds_Contracted);
            }

            if (ds_Contracted != null)
            {
                DataView dv = ds_Contracted.Tables[0].DefaultView;
                grContracted.SessionKey = GetSessionKey(sessionKey);
                grContracted.SessionKeyIndex = 0;
                grContracted.SessionKeyFilter = dv.RowFilter;
                grContracted.SessionKeyColumnHeadersIndex = 1;

                string ddlKey = sessionKey + "DDL";
                SetSession(ddlKey, Hipocrate.DB.DBConnection.GetData("select Code_Indicator + ': ' + Name_Indicator as Indicator FROM Contracted_Values"));
                ddlKey = GetSessionKey(ddlKey);

                grContracted.DateTimeFormat = "MMM yyyy";
                grContracted.DateTimeColumn = new string[] { "StartDate", "EndDate" };
                grContracted.DropDownColumns = new string[] { "Indicator" };
                grContracted.DropDownArguments = new string[][] {
						new string[] {ddlKey, "0", "Indicator", "Indicator"}
				    };
                grContracted.HiddenColumns = new string[] { "Code_Indicator" };

                grContracted.DataSource = dv;
                grContracted.DataBind();

                foreach (DataControlField f in grContracted.Fields) // sau: grContracted.Columns
                    if (f is DropDownField) // sau: f.HeaderText.Contains("Indicator")
                    {
                        //output.Text += "'" + f.GetType().ToString() + "',";
                        (f as DropDownField).ReadOnly = true;
                    }
            }
        }

        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
            output.Text = ex.ToString() + "<!--" + sqlQuery + "-->";
        }
    }

    private void CheckGridColumns()
    {
        //disabling for now, since it manages to achieve the exact OPPOSITE goal: hides the DDLs on insert, and leaves them active on edit... :-|
        foreach (DataControlField f in grContracted.Fields) // sau: grContracted.Columns
            if (f is DropDownField) // sau: f.HeaderText.Contains("Indicator")
            {
                //output.Text += f.HeaderText + ": '" + (f as DropDownField).ReadOnly.ToString() + "', ";
                //(f as DropDownField).ReadOnly = true;
            }
    }

    protected void validatedReports_ItemDataBound(object sender, DataGridItemEventArgs e)
    {
        if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            DataRowView drv = e.Item.DataItem as DataRowView;
            foreach (TableCell cell in e.Item.Cells)
                foreach (Control c in cell.Controls)
                    if (c is IButtonControl)
                    {
                        string commandName = (c as IButtonControl).CommandName;
                        if (commandName.Equals("View"))
                        {
                            (c as LinkButton).CommandArgument = drv["IDMonth"].ToString() + "," + drv["IDYear"].ToString();
                            (c as LinkButton).Text = (e.Item.ItemIndex + 1).ToString();
                        }
                        if (commandName.Equals("Hide"))
                            (c as Button).CommandArgument = drv["ID"].ToString(); // == IRFH.ID
                    }
        }
    }

    protected void validatedReports_ItemCommand(object source, DataGridCommandEventArgs e)
    {
        if (e.CommandName.Equals("View"))
        {
            string[] arguments = e.CommandArgument.ToString().Split(',');
            strMonthVerif.SelectedValue = arguments[0];
            strYearVerif.SelectedValue = arguments[1];
            viewRaport_Click(null, null);
        }
        if (e.CommandName.Equals("Hide"))
        {
            try
            {
                Hipocrate.DB.DBConnection.Execute("IND_FACTORS_REP_SAVE",
                    new string[] { "@IdFactor", "@IDHistory", "@Month", "@Year", "@Results", "@NewResults", "@UserID", "@bUpdate" },
                    new object[] { -1, e.CommandArgument, -1, -1, decimal.Zero, DBNull.Value, string.Empty, true });
            }
            catch { throw; } //TODO: should this check for a "too many params" error?
            LoadData(true);
        }
    }

    System.Collections.Generic.Dictionary<object, bool> implemented = null;
    bool isValidated = false;
    protected void viewRaport_Click(object sender, EventArgs e)
    {
        if ((strMonthVerif.SelectedValue.Trim().Length == 0) || (strYearVerif.SelectedValue.Trim().Length == 0))
        {
            this.Master.SetMessage("Parametrii incorecti.", true);
            return;
        }
        procedureParamNames = new string[2] { "@Month", "@Year" };
        procedureParamValues = new object[2] { strMonthVerif.SelectedValue, strYearVerif.SelectedValue };

        selectie.Visible = false;
        valori.Visible = true;

        string sql = string.Format(@"SELECT (SELECT TOP 1 MonthName from MONTH_NAMES where ID = {0}) AS MonthName,
							(SELECT TOP 1 Code from Years where ID = {1}) AS YearName", procedureParamValues[0], procedureParamValues[1]);
        try
        {
            DataSet ds = Hipocrate.DB.DBConnection.GetData(sql);
            monthName.Text = ds.Tables[0].Rows[0]["MonthName"].ToString();
            yearName.Text = ds.Tables[0].Rows[0]["YearName"].ToString();

            sql = string.Format(@"SELECT IFac.*,IRF.Result,IRF.NewResult , ISNULL(IRF.Valid,0) AS Validated
				FROM IND_FACTORS IFac
				LEFT JOIN IND_REPORT_FACTORS IRF ON IFac.ID = IRF.IDFactor AND IRF.Valid = 1
				AND IRF.IDMONTH = {0} AND IRF.IDYEAR = {1}
				order by IFac.IsCalculated DESC, IFac.TypeID DESC , IFac.Name ASC", procedureParamValues[0], procedureParamValues[1]);
            ds = Hipocrate.DB.DBConnection.GetData(sql);
            if (ds.Tables[0].Rows.Count == 0)
            {
                noReport.Visible = true;
                reportValues.Visible = false;
                return;
            }
            foreach (DataRow r in ds.Tables[0].Rows)
                if ((bool)(r["Validated"]))
                {
                    isValidated = true;
                    break;
                }
            validState.Text = (isValidated ? "validat" : "nevalidat");
            if (!isValidated)
                ComputeValues(ds.Tables[0]);

            DataTable dtFactorTypes = Hipocrate.DB.DBConnection.GetData("SELECT ID, Description FROM IND_FACTORSType WHERE Valid = 1").Tables[0];
            implemented = new System.Collections.Generic.Dictionary<object, bool>(dtFactorTypes.Rows.Count);

            System.Collections.Generic.List<int> breakPoints = new System.Collections.Generic.List<int>(1 + dtFactorTypes.Rows.Count);
            separatorLines = new System.Collections.Generic.List<string>(1 + breakPoints.Capacity);
            separatorLines.Add("&nbsp;");
            int nRowsToInsert = 2, offset = 0;
            for (int rowIndex = 0; rowIndex < ds.Tables[0].Rows.Count; ++rowIndex)
            {
                DataRow currentRow = ds.Tables[0].Rows[rowIndex];
                DataRow previousRow = (rowIndex > 0) ? ds.Tables[0].Rows[rowIndex - 1] : null;
                if ((rowIndex == 0) || !currentRow["TypeID"].Equals(previousRow["TypeID"]))
                {
                    breakPoints.Add(rowIndex + offset);
                    string typeDescription = "Valori care nu se calculeaza in Hipocrate";
                    object currentTypeId = currentRow["TypeID"];
                    if (!implemented.ContainsKey(currentTypeId))
                    {
                        foreach (DataRow r in ds.Tables[0].Rows)
                            if (currentTypeId.Equals(r["TypeID"]))
                                if (r["Result"] != DBNull.Value)
                                {
                                    implemented[currentTypeId] = true;
                                    break;
                                }
                        if (!implemented.ContainsKey(currentTypeId))
                            implemented[currentTypeId] = false;
                    }
                    if ((bool)(currentRow["IsCalculated"]))
                        foreach (DataRow typeInfo in dtFactorTypes.Rows)
                            if (currentTypeId.Equals(typeInfo["id"]))
                            {
                                typeDescription = typeInfo["description"].ToString();
                                if (!implemented[currentTypeId])
                                    typeDescription += " - NEIMPLEMENTAT";
                                break;
                            }
                    separatorLines.Add(typeDescription);
                    offset += nRowsToInsert;
                }
                if (!(bool)(currentRow["IsCalculated"]))
                    break; //ignoring all the rest of changes in TypeID (for the NotCalculated rows).
            }
            if (breakPoints.Count > 0)
            {
                //add separator rows to show group headers
                foreach (DataColumn c in ds.Tables[0].Columns) c.AllowDBNull = true;
                //get title from dtFactorTypes
                DataRow separator;
                for (int item = 0; item < breakPoints.Count; ++item)
                    for (int x = 0; x < nRowsToInsert; ++x)
                    {
                        separator = ds.Tables[0].NewRow();
                        separator["IsCalculated"] = DBNull.Value;
                        separator["Name"] = separatorLines[x > 0 ? 0 : 1 + item]; //inserted in reverse order!
                        ds.Tables[0].Rows.InsertAt(separator, breakPoints[item]);
                    }
            }
            factors = new System.Collections.Generic.List<object>(); //or: factors.Clear();
            results = new System.Collections.Generic.List<object>();
            IsSeparator = new System.Collections.Generic.List<bool>();
            reportValues.DataSource = ds;
            reportValues.DataBind();
            this.ViewState["factors"] = factors.ToArray();
            this.ViewState["results"] = results.ToArray();
        }
        catch (Exception ex)
        {
            this.Master.SetMessage(ex.Message, true);
            validState.Text += "<!--" + ex.ToString() + "-->";
        }
    }

    protected void validare_Click(object sender, EventArgs e)
    {
        try
        {
            int idHistory = SaveHistory();
            object[] newFactors = (object[])(this.ViewState["factors"]);
            object[] dbResults = (object[])(this.ViewState["results"]);
            System.Diagnostics.Debug.Assert(newFactors.Length == dbResults.Length);
            if (newFactors.Length != dbResults.Length)
                throw new ApplicationException("Datele din pagina au fost corupte.");
            string error = "";
            int offset = 0;
            for (int i = 0; i < newFactors.Length; ++i)
            {
                string[] paramNames = new string[] { "@IdFactor", "@IDHistory", "@Month", "@Year", "@Results", "@NewResults", "@UserID" };
                object[] paramValues = new object[] { newFactors[i], idHistory, strMonthVerif.SelectedValue, strYearVerif.SelectedValue, dbResults[i], DBNull.Value, this.Session["StaffId"] ?? -1 };
                int indexForNewResult = 5;
                //seek corresponding textbox:
                while ((reportValues.Items[i + offset].Cells.Count == 1) || IsSeparatorLine(reportValues.Items[i + offset].Cells[0].Text))
                {
                    while (reportValues.Items[i + offset].Cells.Count > 1)
                        reportValues.Items[i + offset].Cells.RemoveAt(1);
                    reportValues.Items[i + offset].Cells[0].HorizontalAlign = HorizontalAlign.Center;
                    reportValues.Items[i + offset].Cells[0].ColumnSpan = reportValues.Columns.Count; // == 4
                    ++offset;
                }
                System.Diagnostics.Debug.Assert(reportValues.Items[i + offset].Cells[0].Text.Equals((i + 1).ToString()));
                if (!reportValues.Items[i + offset].Cells[0].Text.Equals((i + 1).ToString()))
                    //throw new ApplicationException("Cells for #" + i.ToString() + " were not '1', but: " + reportValues.Items[i + offset].Cells.Count.ToString());
                    throw new ApplicationException("Item for #" + i.ToString() + " was: " + reportValues.Items[i + offset].Cells[0].Text);
                if ((dbResults[i] == DBNull.Value) || (dbResults[i] == null) || (dbResults[i].Equals(string.Empty)))
                    continue;
                string newResult = (reportValues.Items[i + offset].Cells[3].Controls[1] as TextBox).Text;
                (reportValues.Items[i + offset].Cells[3].Controls[1] as TextBox).BackColor = System.Drawing.Color.White;
                //debug:
                //reportValues.Items[i + offset].Cells[2].Text = "&gt;" + newResult.ToString() + "&lt;";
                decimal value;
                if (newResult.Length > 0)
                {
                    if (decimal.TryParse(newResult, out value)) //~ IsNumeric
                        paramValues[indexForNewResult] = newResult;
                    else
                    {
                        (reportValues.Items[i + offset].Cells[3].Controls[1] as TextBox).BackColor = System.Drawing.Color.Pink;
                        error += "Factorul #" + (i + 1).ToString() + " nu a putut fi salvat: valoare non-numerica. ";
                        continue;
                    }
                }
                //else it's left as null
                int result = 0;
                try
                {
                    result = Hipocrate.DB.DBConnection.Execute("IND_FACTORS_REP_SAVE", paramNames, paramValues);
                }
                catch (System.Data.SqlClient.SqlException)
                {
                    result = -1;
                }
                if (result == -1)
                {
                    error += "S-a produs o eroare la salvarea factorului #" + (i + 1).ToString() + ". ";
                    output.Text += "<!-- dbVal[" + (i + 1).ToString() + "] = (" + error + (dbResults[i] == null ? "?" : dbResults[i].GetType().ToString()) + ")'" + (dbResults[i] == null ? "null" : dbResults[i].ToString()) + "' -->";
                }
            }
			if (error.Length > 0)
				this.Master.SetMessage(error, true);
			else
			{
				validState.Text = "validat";
				this.Master.SetMessage("Factorii au fost salvati.", false);
				mdlPopup.Show();
				//refresh values:
				viewRaport_Click(null, null);
			}
        }
        catch (NullReferenceException ex)
        {
            this.Master.SetMessage(ex.Message, true);
            validState.Text += "<!--" + ex.ToString() + "-->";
        }
        catch (Exception ex)
        {
            this.Master.SetMessage(ex.Message, true);
            validState.Text += "!<!--" + ex.ToString() + "-->";
        }
    }

    private int SaveHistory()
    {
        //throw new ApplicationException("sID=" + (this.Session["StaffId"] ?? "null").ToString() + ".");
        object result = ExecuteSPWithInOutParams("IND_FACTORS_REP_HISTORY_SAVE",
            new string[] { "@Month", "@Year", "@UserID" },
            new object[] { strMonthVerif.SelectedValue, strYearVerif.SelectedValue, this.Session["StaffId"] ?? -1 },
            "@strOUT")[0].Value;
        return System.Convert.ToInt32(result);
    }

    protected void inapoi_Click(object sender, EventArgs e)
    {
        mdlPopup.Hide();
        valori.Visible = false;
        selectie.Visible = true;
        string month = strMonthVerif.SelectedValue;
        string year = strYearVerif.SelectedValue;
        LoadData(true);
        strMonthVerif.SelectedValue = month;
        strYearVerif.SelectedValue = year;
    }

    private System.Collections.Generic.List<string> separatorLines
    {
        get { return (System.Collections.Generic.List<string>)this.ViewState["separatorLines"]; }
        set { this.ViewState["separatorLines"] = value; }
    }
    private System.Collections.Generic.List<bool> IsSeparator
    {
        get { return (System.Collections.Generic.List<bool>)this.ViewState["IsSeparator"]; }
        set { this.ViewState["IsSeparator"] = value; }
    }

	private void ComputeValues(DataTable dt)
	{
		foreach (DataRow dr in dt.Rows)
		{
			try
			{
				dr["Result"] = ExecuteSPWithInOutParams(dr["ValidationProcedure"].ToString(), procedureParamNames, procedureParamValues, "@decOUT")
					[0].Value;
			}
			catch (System.Data.SqlClient.SqlException ex)
			{
				dr["Result"] = decimal.MinValue;
				dr["Description"] = ex.Message;
			}
		}
	}

    private bool boolShownEmptyRow = false;
    private int shownEmptyRows = 0;
    private System.Collections.Generic.List<object> factors = new System.Collections.Generic.List<object>();
    private System.Collections.Generic.List<object> results = new System.Collections.Generic.List<object>();
    private string[] procedureParamNames = null;
    private object[] procedureParamValues = null;
    protected void reportValues_ItemDataBound(object sender, DataGridItemEventArgs e)
    {
        if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            e.Item.CssClass = (e.Item.ItemIndex % 2 == 1 ? "tdn" : "tdngris8");
            DataRowView drv = e.Item.DataItem as DataRowView;
            if (drv["IsCalculated"] == DBNull.Value) // added on-demand in the middle; all the db rows have non-null values
            {
                IsSeparator.Add(true);
                int colSpan = e.Item.Cells.Count;
                while (e.Item.Cells.Count > 1)
                    e.Item.Cells.RemoveAt(1);
                e.Item.Cells[0].Text = drv["Name"].ToString();
                if (boolShownEmptyRow)
                    e.Item.Cells[0].CssClass = "tdh"; //blue background for the "section" header text
                boolShownEmptyRow = !boolShownEmptyRow;
                e.Item.Cells[0].HorizontalAlign = HorizontalAlign.Center;
                e.Item.Cells[0].ColumnSpan = colSpan;
                ++shownEmptyRows;
            }
            else
            {
				IsSeparator.Add(false);
				//compute current factor number:
				e.Item.Cells[0].Text = (e.Item.ItemIndex + 1 - shownEmptyRows).ToString();
				object initialValue = drv["Result"];
				object currentValue = drv["NewResult"];
				object currentTypeId = drv["TypeID"];
				string displayedValue = "";
				if (!implemented[currentTypeId])
				{
					(e.Item.Cells[3].Controls[1] as TextBox).Enabled = false;
				}
				else
				{
					bool exception = initialValue.Equals(string.Empty) || initialValue.Equals(decimal.MinValue);
					if (!isValidated) //&& (bool)(drv["IsCalculated"]))
					{
						//computing the value isn't being done here anymore, since it was required earlier...
						if (exception)
						{
							(e.Item.Cells[3].Controls[1] as TextBox).BackColor = System.Drawing.Color.Pink;
							(e.Item.Cells[3].Controls[1] as TextBox).ToolTip = drv["Description"].ToString();
						}
					}
					if (initialValue == DBNull.Value)
						initialValue = 0;
					if (!exception)
						try
						{
							displayedValue = System.Convert.ToInt64(initialValue).ToString();
						}
						catch (FormatException)
						{
							displayedValue = "Cannot parse: '" + initialValue + "'";
						}
						catch (InvalidCastException)
						{
							displayedValue = ""; //initialValue == DBNull.Value
						}
					else
					{
						displayedValue = "<i>(eroare acces SQL!)</i>";
					}
					e.Item.Cells[2].Text = displayedValue;
					displayedValue = displayedValue.RemoveHtml();
					//debug: e.Item.Cells[2].Text = BuildControlTree(e.Item.Cells[3], 0);
					try
					{
						(e.Item.Cells[3].Controls[1] as TextBox).Text =
							currentValue == DBNull.Value ?
							displayedValue :
							System.Convert.ToInt64(currentValue).ToString();
					}
					catch (FormatException)
					{
						(e.Item.Cells[3].Controls[1] as TextBox).Text = "Cannot parse: '" + currentValue + "'";
					}
				}
				//save values:
                factors.Add(drv["ID"]);
                results.Add(displayedValue);
            }
        }
    }

    protected void reportValues_ItemCreated(object sender, DataGridItemEventArgs e)
    {
        if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
        {
            //recreate the separator lines...
            //if (IsSeparatorLine(e.Item.Cells[0].Text)) //not working anymore... ".Text" will always be empty at this point... Also, e.Item.Cells[0].ColumnSpan == 0. (?!)
            if ((IsSeparator != null) && (IsSeparator.Count > e.Item.ItemIndex) && IsSeparator[e.Item.ItemIndex])
            {
                while (e.Item.Cells.Count > 1)
                    e.Item.Cells.RemoveAt(1);
                //if (!e.Item.Cells[0].Text.Equals(separatorLines[0])) //empty contents
                //    e.Item.Cells[0].CssClass = "tdh";
                e.Item.Cells[0].HorizontalAlign = HorizontalAlign.Center;
                e.Item.Cells[0].ColumnSpan = reportValues.Columns.Count; // == 4
            }
            //else
            //e.Item.CssClass = (e.Item.ItemIndex % 2 == 1 ? "tdn" : "tdngris8");
        }
    }

    private bool IsSeparatorLine(string currentFirstCellContents)
    {
        foreach (string line in separatorLines)
            if (currentFirstCellContents.Equals(line))
                return true;
        return false;
    }

    private string BuildControlTree(Control root, int level)
    {
        string prefix = new string('*', 3 * level);
        string result = prefix + root.ID + " (" + root.GetType().ToString() + ")<br/>";
        result += "vvv<br/>";
        foreach (Control c in root.Controls)
            result += BuildControlTree(c, level + 1);
        result += "^^^<br/>";
        return result;
    }

    private System.Collections.Generic.List<System.Data.SqlClient.SqlParameter> ExecuteSPWithInOutParams(string spName, string[] paramNames, object[] paramValues, params string[] outParamNames)
    {
        System.Data.SqlClient.SqlConnection connection = null;
        try
        {
            connection = new System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["FrameworkHipo"].ConnectionString);
            connection.Open();

            System.Data.SqlClient.SqlCommand cmd = connection.CreateCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = spName;
            for (int i = 0; i < paramNames.Length; ++i)
                cmd.Parameters.AddWithValue(paramNames[i], paramValues[i]);
            System.Collections.Generic.List<System.Data.SqlClient.SqlParameter> outParams = new System.Collections.Generic.List<System.Data.SqlClient.SqlParameter>();
            foreach (string op in outParamNames)
            {
                System.Data.SqlClient.SqlParameter p = new System.Data.SqlClient.SqlParameter();
                p.ParameterName = op;
                p.Direction = ParameterDirection.Output;
                p.SqlDbType = SqlDbType.Decimal;
                outParams.Add(p);
                cmd.Parameters.Add(p);
            }

            cmd.CommandTimeout = 2500;
            cmd.ExecuteNonQuery();

            return outParams;
        }
        finally
        {
            if (connection != null)
                connection.Close();
        }
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        try
        {
            DataSet ds_Contracted = GetSessionDataSet(sessionKey);

            foreach (DataRow r in ds_Contracted.Tables[grContracted.SessionKeyIndex].Rows)
                if (r.RowState != DataRowState.Deleted)
                    r["Code_Indicator"] = GetCodIndicator(r["Indicator"]);

            Hipocrate.DB.DBConnection.SaveAll(ds_Contracted,
                    new object[] { 
						new object[] { "Contracted_Insert", new string[] { "Code_Indicator", "Contracted_Value", "StartDate", "EndDate" } }
					},
                    new object[] { 
						new object[] { "Contracted_Update", new string[] { "ID", "Code_Indicator", "Contracted_Value", "StartDate", "EndDate" } }
					},
                    new object[] { 
						new object[] { "Contracted_Delete", new string[] { "ID" } }
					}
            );
            this.SetMessage("Updated.", false);
            Load_Grid(true);
        }
        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
        }
    }

    private object GetCodIndicator(object selectedInDropDown)
    {
        string value = selectedInDropDown.ToString();
        int positionOfSeparator = value.IndexOf(": ");
        if (positionOfSeparator < 0)
            return DBNull.Value;
        return value.Substring(0, positionOfSeparator);
    }

    private string GetSqlQueryForContracts()
    {
        //SetMessage("Filtering on " + startValDate.SelectedDate.Value.Month.ToString() + " and " + endValDate.SelectedDate.Value.Month.ToString(), false); //NB: doesn't account for changes :(
        //SetMessage("Filtering on " + startValDateStr.Text + " and " + endValDateStr.Text, false); //NB: these were empty, but eventually corrected themselves :-"
        DateTime startDate = DateTime.Parse("1 " + startValDateStr.Text);
        startValDate.SelectedDate = startDate;
        DateTime endDate = DateTime.Parse("1 " + endValDateStr.Text).AddMonths(1).AddSeconds(-1);
        endValDate.SelectedDate = endDate;

        //@"select cvh.[ID], cvh.[Contracted_Value], cvh.[StartDate], cvh.[EndDate], cvh.[Code_Indicator], cv.[Name_Indicator] from Contracted_Value_History  cvh
        //                  left join Contracted_Values cv on cv.Code_Indicator = cvh.Code_Indicator order by cvh.Code_Indicator, cvh.EndDate DESC"
        return string.Format(@"select cvh.[ID], cvh.[Contracted_Value], cvh.[StartDate], cvh.[EndDate], cvh.[Code_Indicator], cvh.[Code_Indicator] + ': ' + cv.[Name_Indicator] as Indicator from Contracted_Value_History  cvh
								left join Contracted_Values cv on cv.Code_Indicator = cvh.Code_Indicator
								where ((cvh.[StartDate] < cvh.[EndDate]) and ((cvh.[StartDate] between '{0}' and '{1}') or (cvh.[EndDate] between '{0}' and '{1}'))) or
									((cvh.[StartDate] is null or cvh.[StartDate] <= '{0}') and (cvh.[EndDate] is null or cvh.[EndDate] >= '{1}'))
								order by cvh.Code_Indicator, cvh.EndDate DESC", startDate.ToString("yyyy-MM-dd"), endDate.ToString("yyyy-MM-dd HH:mm:ss"));
    }
    public void btnFilter_Click(object sender, EventArgs e)
    {
        Load_Grid(true);
    }

    protected void dateIntervalChanged(object sender, EventArgs e)
    {
        btnFilter_Click(null, null);
    }

    protected void CheckInterval(object sender, EventArgs e)
    {
        CheckInterval(true);
    }
    private void CheckInterval(bool showMessage)
    {
        //check if all the months between monthstart and monthend have valid reports
        int nStartAt = int.Parse(strMonthStart.SelectedValue);
        int nEndAt = int.Parse(strMonthEnd.SelectedValue);
        int year = int.Parse(strYear.SelectedValue);
        bool allOk = false;
        string sqlQuery = string.Format(@"SELECT count(*) FROM IND_REPORT_FACTORS_HISTORY h
			WHERE EXISTS (SELECT * FROM IND_REPORT_FACTORS WHERE (IDHistory = h.ID) AND (Valid = 1))
			AND h.IDYear = {0} AND h.IDMonth >= {1} AND h.IDMonth <= {2}", year, nStartAt, nEndAt);
        try
        {
            DataSet result = Hipocrate.DB.DBConnection.GetData(sqlQuery);
            int count = int.Parse(result.Tables[0].Rows[0][0].ToString());
            allOk = count == (nEndAt + 1 - nStartAt);
        }
        catch (Exception ex)
        {
            this.SetMessage(ex.Message, true);
            output.Text = sqlQuery;
        }
        if (showMessage)
            if (!allOk)
                if (nStartAt == nEndAt)
                    SetMessage("Luna selectata nu are raport validat!", true);
                else
                    SetMessage("Unele luni intermediare nu au rapoarte validate.", true);
            else
                SetMessage("Exista toate rapoartele intermediare si sunt validate.", false);
        btnReport.Enabled = allOk;
    }

    protected void imgDelete_Click(object sender, EventArgs e)
    {
        ImageButton btnDelete = sender as ImageButton;
        GridViewRow row = (GridViewRow)btnDelete.NamingContainer;

        DataView dv = new DataView((GetSessionDataSet("ds_Contracted")).Tables[0]);
        dv.RowFilter = "ID = " + Convert.ToString(this.grContracted.DataKeys[row.RowIndex].Value);
        dv[0].Row.Delete();

        grContracted.DataBind();
    }
}
